-- with v8.Handles, ;
with v8.Class_Isolate, v8.Class_Context;
with v8.Class_Message, v8.Class_Value, v8.Class_Object;
with v8.Class_Retained_Object_Info;
package v8.Class_V8 is

   type Fatal_Error_Callback is access procedure
     (Location : String;
      Message  : String);

   type Allow_Code_Generation_From_Strings_Callback is access function
     (local_context : v8.Class_Context.Pointer
     ) return bool;

   type Message_Callback is access procedure
     (Message : v8.Class_Message.Pointer; -- Handle<Message>
      Data : v8.Class_Value.Pointer); -- Handle<Value>

   type Failed_Access_Check_Callback is access procedure
     (target : v8.Class_Object.Pointer;
      access_typ : Access_Type.Enum;
      data : v8.Class_Value.Pointer);

   type Counter_Lookup_Callback is access function
     (name : String
     ) return access int;
   -- return counter address by counter name

   type Create_Histogram_Callback is access function
     (name    : chars_ptr;
      min     : int;
      max     : int;
      buckets : size_t
     ) return void_ptr;

   type Add_Histogram_Sample_Callback is access procedure
     (histogram : void_ptr;
      sample : int);

   type GC_Prologue_Callback is access procedure
     (typ : GC_Type.Enum;
      flags : GC_Callback_Flags.Enum);

   type Global_GC_Prologue_Callback is access procedure;

   type GC_Epilogue_Callback is access procedure
     (typ : GC_Type.Enum;
      flags : GC_Callback_Flags.Enum);
   pragma Convention (C, GC_Epilogue_Callback);

   type Memory_Allocation_Callback is access procedure
     (space : Object_Space.Enum;
      action : Allocation_Action.Enum;
      size : int);

   type Entropy_Source is access function
     (Buffer : Address;
      Length : C.size_t
     ) return Bool;
   pragma Convention(C, Entropy_Source);

   procedure Set_Fatal_Error_Handler (callback : Fatal_Error_Callback);
   -- Set the callback to invoke in case of fatal errors.


   procedure Set_Allow_Code_Generation_From_Strings_Callback
     (that : Allow_Code_Generation_From_Strings_Callback);
   -- Set the callback to invoke to check if code generation from
   -- strings should be allowed.

   procedure Ignore_Out_Of_Memory_Exception;
   --  Ignore out-of-memory exceptions.
   --
   --  V8 running out of memory is treated as a fatal error by default.
   --  This means that the fatal error handler is called and that V8 is
   --  terminated.
   --
   --  Ignore_Out_Of_Memory_Exception can be used to not treat an
   --  out-of-memory situation as a fatal error.  This way, the contexts
   --  that did not cause the out of memory problem might be able to
   --  continue execution.

   function Is_Dead return bool;
   --  Check if V8 is dead and therefore unusable.  This is the case after
   --  fatal errors such as out-of-memory situations.


   -- The following 4 functions are to be used when V8 is built with
   -- the 'compress_startup_data' flag enabled. In this case, the
   -- embedder must decompress startup data prior to initializing V8.
   --
   -- This is how interaction with V8 should look like:
   --       compressed_data_count : Integer := Get_Compressed_Startup_Data_Count;
   --       compressed_data : Startup_Data(compressed_data_count);
   --   ...
   --       Get_Compressed_Startup_Data (compressed_data);
   --   ... decompress data (compressed_data can be updated in-place) ...
   --       Set_Decompressed_Startup_Data(compressed_data);
   --   ... now V8 can be initialized
   --   ... make sure the decompressed data stays valid until V8 shutdown
   --
   -- A helper class StartupDataDecompressor is provided. It implements
   -- the protocol of the interaction described above, and can be used in
   -- most cases instead of calling these API functions directly.
   function Get_Compressed_Startup_Data_Algorithm return Compression_Algorithm.Enum;
   function Get_Compressed_Startup_Data_Count return Integer;
   procedure Get_Compressed_Startup_Data (compressed_data : in out Startup_Data);
   procedure Set_Decompressed_Startup_Data (decompressed_data : in out Startup_Data);

   function Add_Message_Listener
     (that : Message_Callback;
      data : v8.Class_Value.Pointer := null
     ) return bool;
   -- Adds a message listener.
   --
   -- The same message listener can be added more than once and in that
   -- case it will be called more than once for each message.

   procedure Remove_Message_Listeners (that : Message_Callback);
   -- Remove all message listeners from the specified callback function.

   procedure Set_Capture_Stack_Trace_For_Uncaught_Exceptions
     (capture : bool;
      frame_limit : Integer := 10;
      options     : Stack_Trace_Options.Enum := Stack_Trace_Options.k_Over_View);
   -- Tells V8 to capture current stack trace when uncaught exception occurs
   -- and report it to the message listeners. The option is off by default.

   procedure Set_Flags_From_String (str : String);
   -- Sets V8 flags from a string.

   procedure Set_Flags_From_Command_Line
     (argc : access Integer; -- int* argc
      argv : Address; -- char** argv
      remove_flags : bool);
   -- Sets V8 flags from the command line.

   function Get_Version return String;
   -- Get the version string

   procedure Set_Counter_Function (callback : Counter_Lookup_Callback);
   -- Enables the host application to provide a mechanism for recording
   -- statistics counters.


   -- Enables the host application to provide a mechanism for recording
   -- histograms. The Create_Histogram function returns a
   -- histogram which will later be passed to the Add_Histogram_Sample
   -- function.
   procedure Set_Create_Histogram_Function (callback : Create_Histogram_Callback);
   procedure Set_Add_Histogram_Sample_Function (callback : Add_Histogram_Sample_Callback);

   procedure Enable_Sliding_State_Window;
   -- Enables the computation of a sliding window of states. The sliding
   -- window information is recorded in statistics counters.

   procedure Set_Failed_Access_Check_Callback_Function (callback : Failed_Access_Check_Callback);
   -- Callback function for reporting failed access checks

   procedure Add_GC_Prologue_Callback
     (callback       : GC_Prologue_Callback;
      gc_type_filter : GC_Type.Enum := GC_Type.k_All);
   -- Enables the host application to receive a notification before a
   -- garbage collection.  Allocations are not allowed in the
   -- callback function, you therefore cannot manipulate objects (set
   -- or delete properties for example) since it is possible such
   -- operations will result in the allocation of objects. It is possible
   -- to specify the GC_Type filter for your callback. But it is not possible to
   -- register the same callback function two times with different
   -- GC_Type filters.

   procedure Remove_GC_Prologue_Callback (callback : GC_Prologue_Callback);
   -- This function removes callback which was installed by
   -- Add_GC_Prologue_Callback function.

   procedure Set_Global_GC_Prologue_Callback (arg1 : Global_GC_Prologue_Callback);
   -- The function is deprecated. Please use Add_GC_Prologue_Callback instead.
   -- Enables the host application to receive a notification before a
   -- garbage collection.  Allocations are not allowed in the
   -- callback function, you therefore cannot manipulate objects (set
   -- or delete properties for example) since it is possible such
   -- operations will result in the allocation of objects.

   procedure Add_GC_Epilogue_Callback
     (callback       : GC_Epilogue_Callback;
      gc_type_filter : GC_Type.Enum := GC_Type.k_All);
   -- Enables the host application to receive a notification after a
   -- garbage collection.  Allocations are not allowed in the
   -- callback function, you therefore cannot manipulate objects (set
   -- or delete properties for example) since it is possible such
   -- operations will result in the allocation of objects. It is possible
   -- to specify the GC_Type filter for your callback. But it is not possible to
   -- register the same callback function two times with different
   -- GC_Type filters.

   procedure Remove_GC_Epilogue_Callback (callback : GC_Epilogue_Callback);
   -- This function removes callback which was installed by
   -- Add_GC_Epilogue_Callback function.

   procedure Set_Global_GC_Epilogue_Callback (callback : Global_GC_Prologue_Callback);
   -- The function is deprecated. Please use Add_GC_Epilogue_Callback instead.
   -- Enables the host application to receive a notification after a
   -- major garbage collection.  Allocations are not allowed in the
   -- callback function, you therefore cannot manipulate objects (set
   -- or delete properties for example) since it is possible such
   -- operations will result in the allocation of objects.

   procedure Add_Memory_Allocation_Callback
     (callback : Memory_Allocation_Callback;
      space : Object_Space.Enum;
      action   : Allocation_Action.Enum);
   -- Enables the host application to provide a mechanism to be notified
   -- and perform custom logging when V8 Allocates Executable Memory.

   procedure Remove_Memory_Allocation_Callback (callback : Memory_Allocation_Callback);
   -- This function removes callback which was installed by
   -- Add_Memory_Allocation_Callback function.

   procedure Add_Object_Group
     (objects : v8.Class_Object.Object_Array;
      info    : v8.Class_Retained_Object_Info.Pointer := null);
   -- Allows the host application to group objects together. If one
   -- object in the group is alive, all objects in the group are alive.
   -- After each garbage collection, object groups are removed. It is
   -- intended to be used in the before-garbage-collection callback
   -- function, for instance to simulate DOM tree connections among JS
   -- wrapper objects.
   -- See v8-profiler.h for Retained_Object_Info interface description.

   procedure Add_Implicit_References
     (persist_parent   : v8.CLass_Object.Pointer;
      persist_children : v8.Class_Value.Value_Array);
   -- Allows the host application to declare implicit references between
   -- the objects: if |parent| is alive, all |children| are alive too.
   -- After each garbage collection, all implicit references
   -- are removed.  It is intended to be used in the before-garbage-collection
   -- callback function.

   function Initialize return bool;  -- ../include/v8.h:3039

   procedure Set_Entropy_Source (source : Entropy_Source);
   -- Allows the host application to provide a callback which can be used
   -- as a source of entropy for random number generators.

   function Adjust_Amount_Of_External_Allocated_Memory
     (change_in_bytes : int
     ) return Integer;
   -- Adjusts the amount of registered external memory.  Used to give
   -- V8 an indication of the amount of externally allocated memory
   -- that is kept alive by JavaScript objects.  V8 uses this to decide
   -- when to perform global garbage collections.  Registering
   -- externally allocated memory will trigger global garbage
   -- collections more often than otherwise in an attempt to garbage
   -- collect the JavaScript objects keeping the externally allocated
   -- memory alive.
   --
   -- \param change_in_bytes the change in externally allocated memory
   --   that is kept alive by JavaScript objects.
   -- \returns the adjusted value.

   procedure Pause_Profiler;
   -- Suspends recording of tick samples in the profiler.
   -- When the V8 profiling mode is enabled (usually via command line
   -- switches) this function suspends recording of tick samples.
   -- Profiling ticks are discarded until Resume_Profiler is called.
   --
   -- See also the --prof and --prof_auto command line switches to
   -- enable V8 profiling.

   procedure Resume_Profiler;
   -- Resumes recording of tick samples in the profiler.
   -- See also PauseProfiler.

   function Is_Profiler_Paused return bool;
   -- Return whether profiler is currently paused.

   function Get_Current_Thread_Id return int;
   -- Retrieve the V8 thread id of the calling thread.
   --
   -- The thread id for a thread should only be retrieved after the V8
   -- lock has been acquired with a Locker object with that thread.

   procedure Terminate_Execution (thread_id : int);
   -- Forcefully terminate execution of a JavaScript thread.  This can
   -- be used to terminate long-running scripts.
   --
   -- TerminateExecution should only be called when then V8 lock has
   -- been acquired with a Locker object.  Therefore, in order to be
   -- able to terminate long-running threads, preemption must be
   -- enabled to allow the user of TerminateExecution to acquire the
   -- lock.
   --
   -- The termination is achieved by throwing an exception that is
   -- uncatchable by JavaScript exception handlers.  Termination
   -- exceptions act as if they were caught by a C++ TryCatch exception
   -- handler.  If forceful termination is used, any C++ TryCatch
   -- exception handler that catches an exception should check if that
   -- exception is a termination exception and immediately return if
   -- that is the case.  Returning immediately in that case will
   -- continue the propagation of the termination exception if needed.
   --
   -- The thread id passed to Terminate_Execution must have been
   -- obtained by calling Get_Current_Thread_Id on the thread in question.
   --
   -- \param thread_id The thread id of the thread to terminate.

   procedure Terminate_Execution (the_isolate : v8.Class_Isolate.Pointer := null);
   -- Forcefully terminate the current thread of JavaScript execution
   -- in the given isolate. If no isolate is provided, the default
   -- isolate is used.
   --
   -- This method can be used by any thread even if that thread has not
   -- acquired the V8 lock with a Locker object.
   --
   -- \param isolate The isolate in which to terminate the current JS execution.

   function Is_Execution_Terminating (the_isolate : v8.Class_Isolate.Pointer := null) return bool;
   -- Is V8 terminating JavaScript execution.
   --
   -- Returns true if JavaScript execution is currently terminating
   -- because of a call to TerminateExecution.  In that case there are
   -- still JavaScript frames on the stack and the termination
   -- exception is still active.
   --
   -- \param isolate The isolate in which to check.

   function Dispose return bool;
   -- It should generally not be necessary to dispose v8 before exiting
   -- a process, this should happen automatically.  It is only necessary
   -- to use if the process needs the resources taken up by v8.

   procedure Get_Heap_Statistics (Statistics : out Heap_Statistics);
   -- Get statistics about the heap memory usage.

   function Idle_Notification return bool;
   -- Optional notification that the embedder is idle.
   -- V8 uses the notification to reduce memory footprint.
   -- This call can be used repeatedly if the embedder remains idle.
   -- Returns true if the embedder should stop calling IdleNotification
   -- until real work has been done.  This indicates that V8 has done
   -- as much cleanup as it will be able to do.

   procedure Low_Memory_Notification;
   -- Optional notification that the system is running low on memory.
   -- V8 uses these notifications to attempt to free memory.

   function Context_Disposed_Notification return int;
   -- Optional notification that a context has been disposed. V8 uses
   -- these notifications to guide the GC heuristic. Returns the number
   -- of context disposals - including this one - since the last time
   -- V8 had a chance to clean up.


private

   pragma Convention (C, Allow_Code_Generation_From_Strings_Callback);
   pragma Convention (C, Message_Callback);
   pragma Convention (C, Failed_Access_Check_Callback);
   pragma Convention (C, Create_Histogram_Callback);
   pragma Convention (C, Add_Histogram_Sample_Callback);
   pragma Convention (C, GC_Prologue_Callback);
   pragma Convention (C, Global_GC_Prologue_Callback);
   pragma Convention (C, Memory_Allocation_Callback);

   pragma Import (CPP, Set_Allow_Code_Generation_From_Strings_Callback, "_ZN2v82V841SetAllowCodeGenerationFromStringsCallbackEPFbNS_5LocalINS_7ContextEEEE");
   pragma Import (CPP, Ignore_Out_Of_Memory_Exception, "_ZN2v82V826IgnoreOutOfMemoryExceptionEv");
   pragma Import (CPP, Is_Dead, "_ZN2v82V86IsDeadEv");
   pragma Import (CPP, Get_Compressed_Startup_Data_Algorithm, "_ZN2v82V833GetCompressedStartupDataAlgorithmEv");
   pragma Import (CPP, Get_Compressed_Startup_Data_Count, "_ZN2v82V829GetCompressedStartupDataCountEv");
   pragma Import (CPP, Get_Compressed_Startup_Data, "_ZN2v82V824GetCompressedStartupDataEPNS_11StartupDataE");
   pragma Import (CPP, Set_Decompressed_Startup_Data, "_ZN2v82V826SetDecompressedStartupDataEPNS_11StartupDataE");
   pragma Import (CPP, Add_Message_Listener, "_ZN2v82V818AddMessageListenerEPFvNS_6HandleINS_7MessageEEENS1_INS_5ValueEEEES5_");
   pragma Import (CPP, Remove_Message_Listeners, "_ZN2v82V822RemoveMessageListenersEPFvNS_6HandleINS_7MessageEEENS1_INS_5ValueEEEE");
   pragma Import (CPP, Set_Capture_Stack_Trace_For_Uncaught_Exceptions, "_ZN2v82V841SetCaptureStackTraceForUncaughtExceptionsEbiNS_10StackTrace17StackTraceOptionsE");
   pragma Import (CPP, Set_Flags_From_Command_Line, "_ZN2v82V823SetFlagsFromCommandLineEPiPPcb");
   pragma Import (CPP, Set_Create_Histogram_Function, "_ZN2v82V826SetCreateHistogramFunctionEPFPvPKciijE");
   pragma Import (CPP, Set_Add_Histogram_Sample_Function, "_ZN2v82V829SetAddHistogramSampleFunctionEPFvPviE");
   pragma Import (CPP, Enable_Sliding_State_Window, "_ZN2v82V824EnableSlidingStateWindowEv");
   pragma Import (CPP, Add_GC_Prologue_Callback, "_ZN2v82V821AddGCPrologueCallbackEPFvNS_6GCTypeENS_15GCCallbackFlagsEES1_");
   pragma Import (CPP, Set_Failed_Access_Check_Callback_Function, "_ZN2v82V836SetFailedAccessCheckCallbackFunctionEPFvNS_5LocalINS_6ObjectEEENS_10AccessTypeENS1_INS_5ValueEEEE");
   pragma Import (CPP, Remove_GC_Prologue_Callback, "_ZN2v82V824RemoveGCPrologueCallbackEPFvNS_6GCTypeENS_15GCCallbackFlagsEE");
   pragma Import (CPP, Set_Global_GC_Prologue_Callback, "_ZN2v82V827SetGlobalGCPrologueCallbackEPFvvE");
   pragma Import (CPP, Add_GC_Epilogue_Callback, "_ZN2v82V821AddGCEpilogueCallbackEPFvNS_6GCTypeENS_15GCCallbackFlagsEES1_");
   pragma Import (CPP, Remove_GC_Epilogue_Callback, "_ZN2v82V824RemoveGCEpilogueCallbackEPFvNS_6GCTypeENS_15GCCallbackFlagsEE");
   pragma Import (CPP, Set_Global_GC_Epilogue_Callback, "_ZN2v82V827SetGlobalGCEpilogueCallbackEPFvvE");
   pragma Import (CPP, Add_Memory_Allocation_Callback, "_ZN2v82V827AddMemoryAllocationCallbackEPFvNS_11ObjectSpaceENS_16AllocationActionEiES1_S2_");
   pragma Import (CPP, Remove_Memory_Allocation_Callback, "_ZN2v82V830RemoveMemoryAllocationCallbackEPFvNS_11ObjectSpaceENS_16AllocationActionEiE");
   pragma Import (CPP, Initialize, "_ZN2v82V810InitializeEv");
   pragma Import (CPP, Set_Entropy_Source, "_ZN2v82V816SetEntropySourceEPFbPhjE");
   pragma Import (CPP, Adjust_Amount_Of_External_Allocated_Memory, "_ZN2v82V837AdjustAmountOfExternalAllocatedMemoryEi");
   pragma Import (CPP, Pause_Profiler, "_ZN2v82V813PauseProfilerEv");
   pragma Import (CPP, Resume_Profiler, "_ZN2v82V814ResumeProfilerEv");
   pragma Import (CPP, Is_Profiler_Paused, "_ZN2v82V816IsProfilerPausedEv");
   pragma Import (CPP, Get_Current_Thread_Id, "_ZN2v82V818GetCurrentThreadIdEv");
   pragma Import (CPP, Is_Execution_Terminating, "_ZN2v82V822IsExecutionTerminatingEPNS_7IsolateE");
   pragma Import (CPP, Dispose, "_ZN2v82V87DisposeEv");
   pragma Import (CPP, Get_Heap_Statistics, "_ZN2v82V817GetHeapStatisticsEPNS_14HeapStatisticsE");
   pragma Import (CPP, Idle_Notification, "_ZN2v82V816IdleNotificationEv");
   pragma Import (CPP, Low_Memory_Notification, "_ZN2v82V821LowMemoryNotificationEv");
   pragma Import (CPP, Context_Disposed_Notification, "_ZN2v82V827ContextDisposedNotificationEv");
end V8.Class_V8;
